//////////////////////////////////////////////////////////////////////////
//
// GAM204
// State Manager
// StateManager.cpp
// 
// Grant Johnson
// Qantm College
// 27/10/2010
//
//////////////////////////////////////////////////////////////////////////

#include "StateManager.h"
#include "assert.h"

StateManager::StateManager()
{

}

StateManager::~StateManager()
{
	if(!m_states.empty())
	{
		for(std::vector<ABAppState*>::iterator iter = m_states.begin(); iter != m_states.end(); ++iter)
		{
			ABAppState* pElem = *iter;
			delete pElem;
		}
	}
}

//////////////////////////////////////////////////////////////////////////
//Update the state at the back of the vector
//////////////////////////////////////////////////////////////////////////
void StateManager::Update(float a_dt)
{
	assert(!m_states.empty());
	m_states.back()->Update(a_dt);
}


//////////////////////////////////////////////////////////////////////////
//Render the state at the back of the vector
//////////////////////////////////////////////////////////////////////////
void StateManager::Render(float a_dt)
{
	assert(!m_states.empty());
	m_states.back()->Render(a_dt);
}


//////////////////////////////////////////////////////////////////////////
//Push a new state onto the back of the vector
//
//This will cause the state previously at the back of the vector to run
//their onPause function before running the onEnter function of the new
//state.
//////////////////////////////////////////////////////////////////////////
void StateManager::PushState(ABAppState *pState)
{
	m_states.push_back(pState);
	m_states.back()->OnEnter();
}

//////////////////////////////////////////////////////////////////////////
//Pop off the current state on the back of the vector
//
//This will run onPause and onExit functions of the state on the back
//of the vector to clean up the state. It then pops it off the state and
//runs onResume on the new state at the back of the vector.
//////////////////////////////////////////////////////////////////////////
void StateManager::PopState()
{
	assert(!m_states.empty());
	m_states.back()->OnPause();
	m_states.back()->OnExit();
	m_states.pop_back();
	m_states.back()->OnResume();
}

//////////////////////////////////////////////////////////////////////////
//Change the state at the back of the vector to the one passed in
//
//This is similar to the PushState function, however, ChangeState will
//run onExit and pop off the state on the back of the vector, before
//pushing a new state onto the back and running its onEnter function.
//////////////////////////////////////////////////////////////////////////
void StateManager::ChangeState(ABAppState *pState)
{
	if (!m_states.empty())
	{
		m_states.back()->OnExit();
		m_states.pop_back();
	}

	m_states.push_back(pState);
	m_states.back()->OnEnter();
}


//////////////////////////////////////////////////////////////////////////
//Return the current state
//
//This will return the state at the back of the states vector.
//////////////////////////////////////////////////////////////////////////
ABAppState* StateManager::GetCurrentState()
{
	if (!m_states.empty())
	{
		return m_states.back();
	}

	return NULL;
}

